#include "usart1.h"
#include <string.h>
#include <stdio.h>


void usart1_init(void)
{
	GPIO_InitTypeDef gpio_value;
	USART_InitTypeDef usart1_value;
	
	// 使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
	
	// 初始化GPIO
	gpio_value.GPIO_Pin = GPIO_Pin_10;
	gpio_value.GPIO_Mode = GPIO_Mode_IN_FLOATING;  // 浮空输入
	gpio_value.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpio_value);
	
	gpio_value.GPIO_Pin = GPIO_Pin_9;
	gpio_value.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
	GPIO_Init(GPIOA, &gpio_value);
	
	// 初始化USART1
	usart1_value.USART_BaudRate = 115200;
	usart1_value.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	usart1_value.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发
	usart1_value.USART_Parity = USART_Parity_No; // 没有校验位
	usart1_value.USART_StopBits = USART_StopBits_1; // 1bit停止位
	usart1_value.USART_WordLength = USART_WordLength_8b; // 8bit数据位
	USART_Init(USART1, &usart1_value);

	// 使能串口
	USART_Cmd(USART1, ENABLE);
}

void usart1_send_byte(u8 data)
{
	USART_SendData(USART1, data);
	// 检测标记位，判断数据是否发送完成
	while (!USART_GetFlagStatus(USART1, USART_FLAG_TC));
	// 清标记位
	USART_ClearFlag(USART1, USART_FLAG_TC);
}

void usart1_send_str(const char *str)
{
	int len = strlen(str), i;
	for (i = 0; i < len; i++)
		usart1_send_byte(str[i]);
}

void usart1_send_struct(const student *st)
{
	char str[N];
	snprintf(str, sizeof(str), "Id: %u, Age: %u, Name: %s", st->id, st->age, st->name);
	
	usart1_send_str(str);
}

u8 usart1_recv_byte(void) {
    // 阻塞等待数据到达
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    // 读取并返回数据
    return USART_ReceiveData(USART1);
}

char *usart1_recv_str(char *str, u8 max_len) 
{
    u8 c;
    u8 i = 0;

    // 逐字节接收，直到遇到终止符或达到最大长度
    while (i < max_len - 1) {
        c = usart1_recv_byte();  		// 接收1字节
        if (c == '\0' || c == '\n')   	// 终止符
            break;
        str[i++] = c;  	// 存储字符
    }

    str[i] = '\0';  	// 添加字符串终止符
    return str;
}
